using System;
using System.Collections;
using System.Collections.Generic;

namespace Dida
{
	public class BroadcastingSet<T> : ISet<T>
	{
		ISet<T> wrapped;

		public BroadcastingSet(ISet<T> wrapThis)
		{
			wrapped = wrapThis;
		}

		public class ItemAddedArgs : EventArgs
		{
			public T Value;

			internal ItemAddedArgs(T value)
			{
				Value = value;
			}
		}

		public delegate void ItemAddedHandler(object sender, ItemAddedArgs args);
		public event ItemAddedHandler ItemAdded;

		public class ItemRemovedArgs : EventArgs
		{
			public T Value;

			public ItemRemovedArgs(T val)
			{
				Value = val;
			}
		}

		public delegate void ItemRemovedHandler(object sender,ItemRemovedArgs args);
		public event ItemRemovedHandler ItemRemoved;

		public bool Add(T value)
		{
			ItemAddedHandler handler = ItemAdded;
			if(handler != null)
				handler(this,new ItemAddedArgs(value));
			return wrapped.Add(value);
		}

		public ISet<T> GetDifference(ISet<T> b)
		{
			return GetDifference(b);
		}

		void ICollection<T>.Add(T item)
		{
			Add(item);
		}

		public void Clear()
		{
			ItemRemovedHandler handler = ItemRemoved;
			if(handler != null)
			{
				foreach(T val in wrapped)
				{
					handler(this,new ItemRemovedArgs(val));
				}
			}
			wrapped.Clear();
		}

		public bool Contains(T item)
		{
			return wrapped.Contains(item);
		}

		public void CopyTo(T[] array, int arrayIndex)
		{
			wrapped.CopyTo(array,arrayIndex);
		}

		public int Count
		{
			get { return ((ICollection<T>)wrapped).Count; }
		}

		public bool IsReadOnly
		{
			get { return wrapped.IsReadOnly; }
		}

		public bool Remove(T item)
		{
			if(wrapped.Remove(item))
			{
				ItemRemovedHandler handler = ItemRemoved;
				if(handler != null)
				{
					handler(this,new ItemRemovedArgs(item));
				}

				return true;
			}
			else
				return false;
		}

		public System.Collections.Generic.IEnumerator<T> GetEnumerator()
		{
			return wrapped.GetEnumerator();
		}

		System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
		{
			return wrapped.GetEnumerator();
		}

		public void CopyTo(System.Array array, int index)
		{
			CopyTo(array,index);
		}

		public bool IsSynchronized
		{
			get { return wrapped.IsSynchronized; }
		}

		public object SyncRoot
		{
			get { return wrapped.SyncRoot; }
		}

		public object Clone()
		{
			return new BroadcastingSet<T>((ISet<T>)wrapped.Clone());
		}
	}
}